﻿//========================================================= 
/**@file ArgParser.h 
 * @brief 字符串参数配置信息
 * 
 * 如:[Port:<COM1>][Gate:B][Timeout:30],嵌套:[USB:<[VID:<1DFC>][PID:<8903>]>] 
 * 用于虚拟化不同设备,所有设备统一通过string传入参数操作,做
 * 到接口统一 
 *
 * @date 2011-10-17   11:03:40 
 * @author Zhyioo 
 * @version 1.0
 */ 
//--------------------------------------------------------- 
#ifndef _LIBZHOUYB_ARGPARSER_H_
#define _LIBZHOUYB_ARGPARSER_H_
//---------------------------------------------------------
#include "Convert.h"
#include "../container/list.h"
#include "../container/object.h"
using zhou_yb::container::shared_obj;
using zhou_yb::container::RefObject;

#include "../container/container_helper.h"
using zhou_yb::container::list_helper;

#include <sstream>
using std::ostringstream;
using std::istringstream;

#ifdef _WIN32
#   include <WinBase.h>
#else
#   include <sys/time.h>
#endif
//---------------------------------------------------------
namespace zhou_yb {
namespace base {
//---------------------------------------------------------
/// 参数转换器(使用命令空间而不使用类方便后续其他代码文件扩展)  
namespace ArgConvert
{
    //----------------------------------------------------- 
    /// 将字符串string转为指定的格式
    template<class T>
    bool FromString(const string& str, T& val)
    {
        if(str.length() < 1)
            return false;
        istringstream sstream(str);
        sstream >> val;
        return true;
    }
    //----------------------------------------------------- 
    /// 将字符串string转换为指定的格式
    template<class T>
    T FromString(const string& str)
    {
        T tmp;
        FromString<T>(str, tmp);
        return tmp;
    }
    //----------------------------------------------------- 
    /// 将指定格式的数据转换为字符串,需要T支持operator <<或模板特化来实现  
    template<class T>
    string ToString(const T& val)
    {
        ostringstream sstream;
        sstream<<val;
        return sstream.str();
    }
    //----------------------------------------------------- 
    /// 将字符串string转为const char*
    template<>
    const char* FromString<const char*>(const string& str);
    //----------------------------------------------------- 
    /// 将字符串string转为char
    template<>
    bool FromString<char>(const string& str, char& val);
    /// 将字符串string转为string
    template<>
    bool FromString<string>(const string& str, string& val);
    /// 解析str中的pointer数据 
    template<> 
    bool FromString<pointer>(const string& str, pointer& val);
    //----------------------------------------------------- 
    /// 解析str中的ByteBuilder数据 
    template<> 
    bool FromString<ByteBuilder>(const string& str, ByteBuilder& val);
    //----------------------------------------------------- 
    /// 解析str中的bool数据 
    template<>
    bool FromString<bool>(const string& str, bool& val);
    //----------------------------------------------------- 
    /// 解析str中的byte数据
    template<>
    bool FromString<byte>(const string& str, byte& val);
    //----------------------------------------------------- 
    /**
     * @brief 将 pointer 转换为字符串
     * @param [in] val 需要转换的pointer
     * @retval string
     * @return 格式化后的字符串
     *
     * @code
     string str = ArgConvert::ToString((pointer)&log);
     str -> "0x004AF958"
     * @endcode
     *
     */
    template<>
    string ToString<pointer>(const pointer & val);
    //----------------------------------------------------- 
    /// 将char转为string
    template<>
    string ToString<char>(const char& val);
    /// 将string转为string
    template<>
    string ToString<string>(const string& val);
    /// 将ByteArray转换成字符串 
    template<>
    string ToString<ByteArray>(const ByteArray& val);
    /// 将ByteBuilder转换成字符串 
    template<>
    string ToString<ByteBuilder>(const ByteBuilder& val);
    //----------------------------------------------------- 
    /// 将bool转换成字符串 
    template<>
    string ToString<bool>(const bool& val);
    //----------------------------------------------------- 
    /// 将bool转换成字符串
    template<>
    string ToString<byte>(const byte& val);
    //----------------------------------------------------- 
} // namespace ArgConvert
//--------------------------------------------------------- 
/// 枚举接口
template<class T>
struct IEnumerable
{
    /// 迭代接口
    virtual bool MoveNext() = 0;
    /// 重置迭代状态
    virtual void Reset() = 0;
    /// 获取当前的值
    virtual T& Current() = 0;
    /// 获取当前的值(const形式)
    virtual const T& Current() const = 0;
    /// 枚举是否结束
    virtual bool IsEof() const = 0;

    virtual ~IEnumerable() {}
};
/// 枚举器接口
template<class T>
struct IEnumerator
{
    /// 获取枚举器
    virtual T GetEnumerator() const = 0;
};
/// 集合枚举器接口
template<class T>
struct ICollectionEnumerable  : public IEnumerable<T>
{
    /// 增加一个新的值
    virtual T& New() = 0;
    /// 删除当前值
    virtual void Remove() = 0;
};
//--------------------------------------------------------- 
/// 参数值
template<class TKey, class TValue>
struct ArgValue
{
    ArgValue() : Key(), Value() {}

    TKey Key;
    TValue Value;
};
//--------------------------------------------------------- 
/// 针对string类型的模板特化
template<class TKey>
struct ArgValue<TKey, string>
{
    ArgValue() : Key(), Value("") {}

    TKey Key;
    string Value;

    inline bool IsEmpty() const
    {
        return Value.length() < 1;
    }

    template<class T>
    T To(const T& defaultVal = T()) const
    {
        // 空的值
        if(IsEmpty())
            return defaultVal;
        return ArgConvert::FromString<T>(Value);
    }

    template<class T>
    bool Get(T& val) const
    {
        if(IsEmpty())
            return false;
        return ArgConvert::FromString<T>(Value, val);
    }
};
//--------------------------------------------------------- 
/// 键值访问接口
template<class TKey, class TValue>
struct IDictionary
{
    /// 获取指定键的值
    virtual ArgValue<TKey, TValue>& operator[](const TKey& key) = 0;
    /// 获取指定键的值(const)
    virtual const ArgValue<TKey, TValue>& operator[](const TKey& key) const = 0;
    /// 获取指定键的第一个值
    virtual bool Get(const TKey& key, TValue& val) const = 0;
    /// 获取指定键的所有值
    virtual size_t Get(const TKey& key, list_t<TValue>& vals) const = 0;
    /// 新建一个指定键并设置值
    virtual TValue& Put(const TKey& key, const TValue& val) = 0;
};
//----------------------------------------------------- 
template<class T>
class ReadOnlyEnumerator : public IEnumerable<T>
{
protected:
    shared_obj<IEnumerable<T>*> _pEnum;

    void _Destory()
    {
        if(_pEnum.ref_count() < 2 && _pEnum.obj() != NULL)
        {
            delete _pEnum.obj();
            _pEnum.obj() = NULL;
        }
    }
public:
    ReadOnlyEnumerator()
    {
        _pEnum.obj() = NULL;
    }
    virtual ~ReadOnlyEnumerator()
    {
        _Destory();
    }
    ReadOnlyEnumerator& operator =(const ReadOnlyEnumerator& obj)
    {
        _Destory();
        _pEnum = obj._pEnum;
        return (*this);
    }
    template<class TEnum, class TArg>
    bool Create(const TArg& arg, const TEnum*)
    {
        _Destory();
        _pEnum.obj() = new TEnum(arg);
        return true;
    }
    virtual bool MoveNext()
    {
        return _pEnum.obj()->MoveNext();
    }
    virtual void Reset()
    {
        _pEnum.obj()->Reset();
    }
    virtual T& Current()
    {
        return _pEnum.obj()->Current();
    }
    virtual const T& Current() const
    {
        return _pEnum.obj()->Current();
    }
    virtual bool IsEof() const
    {
        return _pEnum.obj()->IsEof();
    }
};
template<class T>
class CollectionEnumerator : public ICollectionEnumerable<T>
{
protected:
    shared_obj<ICollectionEnumerable<T>*> _pEnum;

    void _Destory()
    {
        if(_pEnum.ref_count() < 2 && _pEnum.obj() != NULL)
        {
            delete _pEnum.obj();
            _pEnum.obj() = NULL;
        }
    }
public:
    CollectionEnumerator()
    {
        _pEnum.obj() = NULL;
    }
    virtual ~CollectionEnumerator()
    {
        _Destory();
    }
    CollectionEnumerator& operator =(const CollectionEnumerator& obj)
    {
        _Destory();
        _pEnum = obj._pEnum;
        return (*this);
    }
    template<class TEnum, class TArg>
    bool Create(const TArg& arg, const TEnum*)
    {
        _Destory();
        _pEnum.obj() = new TEnum(arg);
        return true;
    }
    virtual bool MoveNext()
    {
        return _pEnum.obj()->MoveNext();
    }
    virtual void Reset()
    {
        _pEnum.obj()->Reset();
    }
    virtual T& Current()
    {
        return _pEnum.obj()->Current();
    }
    virtual const T& Current() const
    {
        return _pEnum.obj()->Current();
    }
    virtual bool IsEof() const
    {
        return _pEnum.obj()->IsEof();
    }
    virtual T& New()
    {
        return _pEnum.obj()->New();
    }
    virtual void Remove()
    {
        _pEnum.obj()->Remove();
    }
};
//--------------------------------------------------------- 
/// 参数接口
template<class TKey, class TValue>
struct IMapArguments : public IDictionary<TKey, TValue>, 
    public IEnumerator<CollectionEnumerator<ArgValue<TKey, TValue> > >
{
    typedef TKey KeyType;
    typedef TValue ValueType;
    typedef ArgValue<TKey, TValue> ArgType;
    typedef CollectionEnumerator<ArgValue<TKey, TValue> > EnumeratorType;

    /// 返回键值数目
    virtual size_t Count() const = 0;
};
//--------------------------------------------------------- 
/// 基于链表封装的只读枚举器
template<class TList>
class ListReadOnlyEnumerator : public IEnumerable<typename TList::value_type>
{
protected:
    typename TList::iterator _currItr;
    typename TList::iterator _nextItr;
    TList* _pList;
public:
    ListReadOnlyEnumerator(const TList& _list)
    {
        _pList = const_cast<TList*>(&_list);
        Reset();
    }
    virtual bool MoveNext()
    {
        if(IsEof())
            return false;

        ++_nextItr;
        _currItr = _nextItr;
        return !IsEof();
    }
    virtual void Reset()
    {
        _currItr = _pList->begin();
        _nextItr = _pList->begin();
        --_nextItr;
    }
    virtual typename TList::value_type& Current()
    {
        return (*_currItr);
    }
    virtual const typename TList::value_type& Current() const
    {
        return (*_currItr);
    }
    virtual bool IsEof() const
    {
        typename TList::const_iterator itr(_currItr);
        return itr == _pList->end();
    }
};
/// 基于链表封装的枚举器
template<class TList>
class ListEnumerator : public ICollectionEnumerable<typename TList::value_type>
{
protected:
    typename TList::iterator _currItr;
    typename TList::iterator _nextItr;
    TList* _pList;
public:
    ListEnumerator(const TList& _list)
    {
        _pList = const_cast<TList*>(&_list);
        Reset();
    }
    virtual bool MoveNext()
    {
        if(IsEof())
            return false;

        ++_nextItr;
        _currItr = _nextItr;
        return !IsEof();
    }
    virtual void Reset()
    {
        _currItr = _pList->begin();
        _nextItr = _pList->begin();
        --_nextItr;
    }
    virtual typename TList::value_type& Current()
    {
        return (*_currItr);
    }
    virtual const typename TList::value_type& Current() const
    {
        return (*_currItr);
    }
    virtual bool IsEof() const
    {
        typename TList::const_iterator itr(_currItr);
        return itr == _pList->end();
    }
    virtual typename TList::value_type& New()
    {
        typename TList::iterator itr = _pList->push_back();
        return (*itr);
    }
    virtual void Remove()
    {
        _currItr = list_helper<typename TList::value_type>::erase(*_pList, _currItr);
        _nextItr = _currItr;
    }
};
/// 基于list实现的Map键值枚举操作
template<class TKey, class TValue>
class MapKeyReadOnlyEnumerator : public IEnumerable<TKey>
{
protected:
    typedef typename IMapArguments<TKey, TValue>::EnumeratorType EnumeratorType;
    EnumeratorType _enumer;
public:
    MapKeyReadOnlyEnumerator(const EnumeratorType& enumer)
    {
        _enumer = enumer;
        Reset();
    }
    virtual ~MapKeyReadOnlyEnumerator() {}
    virtual bool MoveNext()
    {
        return _enumer.MoveNext();
    }
    virtual void Reset()
    {
        _enumer.Reset();
    }
    virtual TKey& Current()
    {
        return _enumer.Current().Key;
    }
    virtual const TKey& Current() const
    {
        return _enumer.Current().Key;
    }
    virtual bool IsEof() const
    {
        return _enumer.IsEof();
    }
};
//--------------------------------------------------------- 
/// 基于Map的枚举器辅助操作
template<class TKey, class TValue>
class ListToMapAdapter : public IDictionary<TKey, TValue>
{
public:
    typedef ArgValue<TKey, TValue> ArgType;
    typedef IEnumerable<ArgType> IEnumerableType;
protected:
    IEnumerableType* _pIEnumerable;
    ArgType _Null;
public:
    ListToMapAdapter(const IEnumerableType& ienumerable)
    {
        _pIEnumerable = const_cast<IEnumerableType*>(&ienumerable);
    }
    virtual ArgType& operator [](const TKey& key)
    {
        _pIEnumerable->Reset();
        while(_pIEnumerable->MoveNext())
        {
            if(_pIEnumerable->Current().Key == key)
            {
                return _pIEnumerable->Current();
            }
        }
        return _Null;
    }
    virtual const ArgType& operator [](const TKey& key) const
    {
        _pIEnumerable->Reset();
        while(_pIEnumerable->MoveNext())
        {
            if(_pIEnumerable->Current().Key == key)
            {
                return _pIEnumerable->Current();
            }
        }
        return _Null;
    }
    virtual bool Get(const TKey& key, TValue& val) const
    {
        _pIEnumerable->Reset();
        while(_pIEnumerable->MoveNext())
        {
            if(_pIEnumerable->Current().Key == key)
            {
                val = _pIEnumerable->Current().Value;
                return true;
            }
        }
        return false;
    }
    virtual size_t Get(const TKey& key, list_t<TValue>& vals) const
    {
        _pIEnumerable->Reset();
        while(_pIEnumerable->MoveNext())
        {
            if(_pIEnumerable->Current().Key == key)
            {
                vals.push_back(_pIEnumerable->Current().Value);
            }
        }
        return false;
    }
    virtual TValue& Put(const TKey& key, const TValue& val)
    {
        ArgType& v = _pIEnumerable->New();
        v.Key = key;
        v.Value = val;
        return v.Value;
    }
};
//--------------------------------------------------------- 
/// 默认的IMapArguments
template<class TKey, class TValue>
class MapArguments : 
    public IMapArguments<TKey, TValue>, 
    public RefObject
{
public:
    //-----------------------------------------------------
    typedef typename IMapArguments<TKey, TValue>::ArgType ArgType;
    typedef typename IMapArguments<TKey, TValue>::EnumeratorType EnumeratorType;
    typedef list_t<ArgType> ListType;
    typedef typename list_t<ArgType>::iterator Iterator;
    typedef typename list_t<ArgType>::const_iterator ConstIterator;
    //-----------------------------------------------------
protected:
    //-----------------------------------------------------
    /// 存放所有保存的数据
    ListType _args;
    /// 查找不到时返回的默认值
    ArgType _Null;
    /// 键值比较函数
    virtual bool _Compare(const TKey& k1, const TKey& k2) const
    {
        return k1 == k2;
    }
    /**
     * @brief 在所有子项中查找是否有指定键值的配置项 
     * @param [in] key 需要查找的键值 
     */
    virtual Iterator _Find(const TKey& key)
    {
        Iterator itr;
        for(itr = _args.begin();itr != _args.end(); ++itr)
        {
            if(_Compare(key, itr->Key))
                return itr;
        }
        return _args.end();
    }
    virtual ConstIterator _Find(const TKey& key) const
    {
        ConstIterator itr;
        for(itr = _args.begin(); itr != _args.end(); ++itr)
        {
            if(_Compare(key, itr->Key))
                return itr;
        }
        return _args.end();
    }
    //----------------------------------------------------- 
public:
    //----------------------------------------------------- 
    /// 拷贝
    static size_t CopyTo(const IMapArguments<TKey, TValue>& from, IMapArguments<TKey, TValue>& to)
    {
        typename IMapArguments<TKey, TValue>::EnumeratorType enumer = from.GetEnumerator();
        size_t count = 0;
        while(enumer.MoveNext())
            to.Put(enumer.Current().Key, enumer.Current().Value);
        return count;
    }
    /// 清空
    static size_t Clear(IMapArguments<TKey, TValue>& map)
    {
        size_t count = 0;
        typename IMapArguments<TKey, TValue>::EnumeratorType enumer = map.GetEnumerator();
        while(enumer.MoveNext())
        {
            enumer.Remove();
            enumer.Reset();
            ++count;
        }
        return count;
    }
    /// 删除键
    static size_t Remove(IMapArguments<TKey, TValue>& map, const TKey& key, bool isRemoveAll = false)
    {
        size_t count = 0;
        typename IMapArguments<TKey, TValue>::EnumeratorType enumer = map.GetEnumerator();
        while(enumer.MoveNext())
        {
            if(enumer.Current().Key == key)
            {
                enumer.Remove();
                ++count;
                if(!isRemoveAll)
                    break;
            }
        }
        return count;
    }
    /// 修改值
    static size_t Modify(IMapArguments<TKey, TValue>& map, const TKey& key, const TValue& val, bool isModifyAll = false)
    {
        size_t count = 0;
        typename IMapArguments<TKey, TValue>::EnumeratorType enumer = map.GetEnumerator();
        while(enumer.MoveNext())
        {
            if(enumer.Current().Key == key)
            {
                enumer.Current().Value = val;
                ++count;
                if(!isModifyAll)
                    break;
            }
        }
        return count;
    }
    /// 设置值并返回是否新增数据,如果键不存在,则添加一个新的健
    static bool Set(IMapArguments<TKey, TValue>& map, const TKey& key, const TValue& val, bool isSetAll = false)
    {
        size_t count = Modify(map, key, val, isSetAll);
        // 没有键值
        if(count < 1)
        {
            map.Put(key, val);
            return true;
        }
        return false;
    }
    /// 获取指定数据,没有则返回Null
    static TValue* OptGet(IMapArguments<TKey, TValue>& map, const TKey& key)
    {
        typename IMapArguments<TKey, TValue>::EnumeratorType enumer = map.GetEnumerator();
        while(enumer.MoveNext())
        {
            if(enumer.Current().Key == key)
                return &enumer.Current().Value;
        }
        return NULL;
    }
    /// 删除指定索引下的键值
    static EnumeratorType IndexOf(IMapArguments<TKey, TValue>& map, uint index)
    {
        typename IMapArguments<TKey, TValue>::EnumeratorType enumer = map.GetEnumerator();
        uint i = 0;
        while(enumer.MoveNext())
        {
            if(i == index)
                break;
            ++i;
        }
        return enumer;
    }
    //----------------------------------------------------- 
    MapArguments()
    {
        IsUniqueKey = false;
    }
    virtual ~MapArguments()
    {
        _args.clear();
    }
    //----------------------------------------------------- 
    /// 是否键值唯一
    bool IsUniqueKey;
    //----------------------------------------------------- 
    virtual EnumeratorType GetEnumerator() const
    {
        EnumeratorType enumer;
        typedef ListEnumerator<ListType> CollectionEnumeratorType;
        CollectionEnumeratorType* pNull = NULL;
        enumer.Create(_args, pNull);
        return enumer;
    }
    //----------------------------------------------------- 
    virtual ArgType& New()
    {
        Iterator itr = _args.push_back();
        return (*itr);
    }
    virtual TValue& Put(const TKey& key)
    {
        Iterator itr;
        if(IsUniqueKey)
        {
            itr = _Find(key);
            if(itr != _args.end())
                return itr->Value;
        }
        itr = _args.push_back();
        itr->Key = key;
        return itr->Value;
    }
    virtual ArgType& operator [](const TKey& key)
    {
        Iterator itr = _Find(key);
        if(itr == _args.end())
            return _Null;
        return (*itr);
    }
    virtual const ArgType& operator [](const TKey& key) const
    {
        ConstIterator itr = _Find(key);
        if(itr == _args.end())
            return _Null;
        return (*itr);
    }
    virtual bool Get(const TKey& key, TValue& val) const
    {
        ConstIterator itr = _Find(key);
        if(itr == _args.end())
            return false;
        val = itr->Value;
        return true;
    }
    virtual size_t Get(const TKey& key, list_t<TValue>& vals) const
    {
        ConstIterator itr;
        size_t count = 0;
        for(itr = _args.begin();itr != _args.end(); ++itr)
        {
            if(_Compare(key, itr->Key))
            {
                vals.push_back(itr->Value);
                ++count;
            }
        }
        return count;
    }
    virtual TValue& Get(const TKey& key)
    {
        return operator[](key).Value;
    }
    virtual const TValue& Get(const TKey& key) const
    {
        return operator[](key).Value;
    }
    virtual TValue& Put(const TKey& key, const TValue& val)
    {
        Iterator itr;
        if(IsUniqueKey)
        {
            itr = _Find(key);
            if(itr != _args.end())
            {
                itr->Value = val;
                return itr->Value;
            }
        }
        itr = _args.push_back();
        itr->Key = key;
        itr->Value = val;
        return itr->Value;
    }
    virtual bool Remove(const TKey& key)
    {
        Iterator itr = _Find(key);
        if(itr == _args.end())
            return false;
        _args.erase(itr);
        return true;
    }
    virtual size_t RemoveAll(const TKey& key)
    {
        size_t count = 0;
        Iterator itr;
        for(itr = _args.begin();itr != _args.end(); ++itr)
        {
            if(_Compare(key, itr->Key))
            {
                itr = list_helper<ArgType>::erase(_args, itr);
                ++count;
            }
        }
        return count;
    }
    virtual bool Contains(const TKey& key)
    {
        return _Find(key) != _args.end();
    }
    virtual size_t Count() const
    {
        return _args.size();
    }
    virtual void Clear()
    {
        _args.clear();
    }
    //----------------------------------------------------- 
};
//--------------------------------------------------------- 
/// 字符串参数接口
typedef IMapArguments<string, string> IStringArguments;
//----------------------------------------------------- 
/// 字符串参数(忽略大小写的键值比较函数)
class StringArguments : public MapArguments<string, string>
{
protected:
    /// 键值比较函数
    virtual bool _Compare(const string& k1, const string& k2) const
    {
        ByteArray s1(k1.c_str(), k1.length());
        ByteArray s2(k2.c_str(), k2.length());

        return StringConvert::Compare(s1, s2, IsIgnoreCase);
    }
public:
    StringArguments(bool isIgnoreCase = true) : MapArguments<string, string>(), IsIgnoreCase(isIgnoreCase) {}
    /// 是否在匹配键值时忽略大小写
    bool IsIgnoreCase;
};
//--------------------------------------------------------- 
/// 字符串解析器接口
struct IStringArgParser
{
    //----------------------------------------------------- 
    /// 解析数据
    virtual size_t Parse(const ByteArray& str, IStringArguments& arg) = 0;
    /// 转换为字符串
    virtual size_t ToString(const IStringArguments& arg, ByteBuilder& str) = 0;
    //----------------------------------------------------- 
};
//--------------------------------------------------------- 
/// 默认的参数配置解析及转换器 
class ArgParser : public IStringArgParser, public RefObject
{
protected:
    //----------------------------------------------------- 
    /// 解析单个结点的配置信息str="[  Port :  <COM1>  ]"
    static bool _ParseValue(const ByteArray& src, string& key, string& val)
    {
        // 至少有2个字符 :数据
        if(src.GetLength() < 2)
            return false;
        ByteArray buf = StringConvert::Trim(src);
        size_t equal = StringConvert::IndexOf(buf, ':');
        if(equal == SIZE_EOF)
            return false;
        // key
        ByteBuilder tmp(8);
        tmp = buf.SubArray(0, equal);
        StringConvert::Trim(tmp);
        key = tmp.GetString();

        // 跳过 ':'
        buf = buf.SubArray(equal + 1, buf.GetLength() - equal - 1);
        ByteArray valArray = StringConvert::Trim(buf);
        size_t valLen = valArray.GetLength();
        if(valLen >= 2 && valArray[0] == '<' && valArray[valLen - 1] == '>')
        {
            valArray = valArray.SubArray(1, valLen - 2);
        }
        // value
        tmp = valArray;
        val = tmp.GetString();
        return true;
    }
    //----------------------------------------------------- 
public:
    //----------------------------------------------------- 
    ArgParser() {}
    //-----------------------------------------------------
    /// 解析配置参数字符串到IMapArguments中
    virtual size_t Parse(const ByteArray& str, IStringArguments& arg)
    {
        size_t count = 0;
        ByteArray buf = StringConvert::Trim(str);
        if(buf.GetLength() < 2)
            return count;
        if(buf[0] != '[' || buf[buf.GetLength() - 1] != ']')
            return count;

        ByteArray subBuf;
        list_t<ArgValue<string, string> >::iterator itr;
        size_t offset = 0;
        while(offset < buf.GetLength())
        {
            string key;
            string val;
            subBuf = StringConvert::Middle(buf.SubArray(offset), '[', ']');
            if(!_ParseValue(subBuf, key, val))
                break;
            arg.Put(key, val);
            ++count;
            offset += subBuf.GetLength();
            offset += 2;
        }
        return count;
    }
    /// 将IMapArguments中的参数转换为字符串的形式
    virtual size_t ToString(const IStringArguments& arg, ByteBuilder& str)
    {
        size_t len = 0;
        list_t<ArgValue<string, string> >::iterator itr;
        string key;
        string val;
        IStringArguments::EnumeratorType enumer = arg.GetEnumerator();
        while(enumer.MoveNext())
        {
            key = enumer.Current().Key;
            val = enumer.Current().Value;

            len += 5;
            len += key.length();
            len += val.length();

            str += '[';
            str.Append(ByteArray(key.c_str(), key.length()));
            str += ":<";
            str.Append(ByteArray(val.c_str(), val.length()));
            str += ">]";
        }
        return len;
    }
    //-----------------------------------------------------
};// class ArgParser
//---------------------------------------------------------
namespace ArgConvert {
//--------------------------------------------------------- 
/**
 * @brief 转换ArgParser中的配置项
 * @param [in] cfg 配置项
 * @param [in] key 主键
 * @param [out] val 找到后的数据
 * @retval bool
 * @return 是否成功找到
 */
template<class T>
bool FromConfig(IStringArguments& cfg, const char* key, T& val)
{
    string tmp;
    if(cfg.Get(key, tmp))
        return FromString<T>(tmp, val);
    return false;
}
//----------------------------------------------------- 
/**
 * @brief 将指定格式的数据转换为ArgParser能够识别的项
 * @param [in] key 转换的主键
 * @param [in] val 需要转换的值
 * @return string 转换后的字符串
 */
template<class T>
string ToConfig(const char* key, const T& val)
{
    string tmp = "[";
    tmp += key;
    tmp += ":<";
    tmp += ToString<T>(val);
    tmp += ">]";

    return tmp;
}
//--------------------------------------------------------- 
} // namespace ArgConvert
//---------------------------------------------------------
//---------------------------------------------------------
/// 获取当前系统时间 
size_t get_current_systime(ByteBuilder& timebuff);
/// 获取当前系统的完整时间(精确到毫秒)
size_t get_minisec_systime(ByteBuilder& timebuff);
//--------------------------------------------------------- 
/// 输出当前时间 2018-10-20 13:51:04.560
string _time_now(const char* fmt = NULL);
//--------------------------------------------------------- 
/// 以16进制输出数据
template<class T>
string _hex(const T& obj, size_t len = sizeof(T))
{
    byte* pObj = reinterpret_cast<byte*>(const_cast<T*>(&obj));
    byte b = 0x00;
    ByteBuilder tmp(2 * len);

    for(size_t i = len;i > 0; --i)
    {
        b = pObj[i - 1] & 0x0F0;
        b >>= HALF_BIT_OFFSET;
        tmp += (b < 0x0A) ? (b + '0') : (b - 0x0A + 'A');

        b = pObj[i - 1] & 0x0F;
        tmp += (b < 0x0A) ? (b + '0') : (b - 0x0A + 'A');
    }

    return tmp.GetString();
}
/// 以16进制输出ByteArray数据
string _hex(const ByteArray& buff);
/// 以16进制输出ByteBuilder数据
string _hex(const ByteBuilder& buff);
//--------------------------------------------------------- 
/// 以16进制输出数字(0xNum)
template<class T>
string _hex_num(const T& num, size_t len = sizeof(T))
{
    string format = "0x";
    format += _hex(num, len);
    return format;
}
//--------------------------------------------------------- 
/// 以二进制位的方式输出 "00000000 11111111"
template<class T>
string _bit(const T& obj, size_t len = sizeof(T))
{
    byte* pObj = reinterpret_cast<byte*>(const_cast<T*>(&obj));
    ByteBuilder tmp((BIT_OFFSET + 1) * len);

    for(size_t i = len;i > 0; --i)
    {
        for(size_t j = 1;j <= static_cast<size_t>(BIT_OFFSET); ++j)
        {
            tmp += static_cast<byte>((pObj[i - 1] & (0x01 << (BIT_OFFSET - j))) == 0x00 ? '0' : '1');
        }
        tmp += static_cast<byte>(' ');
    }
    // 移除最后的空格  
    tmp.RemoveTail();

    return tmp.GetString();
}
//--------------------------------------------------------- 
/// 输出指定数目的空格
string _tab(size_t count, size_t tablen = 4, char flag = ' ');
//--------------------------------------------------------- 
/// 输出树状图结构
string _tree(size_t lv, char flag, size_t width = 4);
/// 输出树状图结点
string _tree_node(size_t lv, char head, char flag, size_t width = 4);
//--------------------------------------------------------- 
/// 以指定的宽度左对齐输出数据
template<class T>
string _left_width(const T& obj, size_t w, char fill = ' ')
{
    string str = ArgConvert::ToString(obj);
    size_t len = str.length();
    while(len < w)
    {
        str += fill;
        ++len;
    }
    return str;
}
//--------------------------------------------------------- 
/// 以指定的宽度右对齐输出数据
template<class T>
string _right_width(const T& obj, size_t w, char fill = ' ')
{
    string tmp = ArgConvert::ToString(obj);
    size_t len = tmp.length();
    if(len >= w)
        return tmp;

    string str = "";
    while(len < w)
    {
        str += fill;
        ++len;
    }
    str += tmp;
    return str;
}
//--------------------------------------------------------- 
/// 以字符串形式输出bool
string _bool(bool b);
//--------------------------------------------------------- 
/// 以字符串形式输出表达式
#define _expression(code) string(#code + string("=") + ArgConvert::ToString(code))
//--------------------------------------------------------- 
} // namespace base
} // namespace zhou_yb
//--------------------------------------------------------- 
#endif // _LIBZHOUYB_ARGPARSER_H_
//=========================================================
